package com.auto.printer.common.annoation;


import cn.hutool.core.util.ReflectUtil;
import cn.hutool.core.util.StrUtil;
import com.auto.printer.common.exception.MyException;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;
import org.springframework.stereotype.Component;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

/**
 * @author wangjie
 * @date 2023年03月15日 17:02
 * @description
 */
@Aspect
@Component
public class CheckParamAspect {

    private Logger logger = LoggerFactory.getLogger(RedisLockAspect.class);

    @Pointcut("@annotation(com.auto.printer.common.annoation.CheckParam)")
    public void init() {
    }


    @Around("init()")
    public Object around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {

        CheckParam checkParam = null;

        Object[] args = proceedingJoinPoint.getArgs();
        String methodName = proceedingJoinPoint.getSignature().getName();
        Class<?> classTarget = proceedingJoinPoint.getTarget().getClass();
        Class<?>[] par = ((MethodSignature) proceedingJoinPoint.getSignature()).getParameterTypes();
        Method objMethod = classTarget.getMethod(methodName, par);

        checkParam = objMethod.getAnnotation(CheckParam.class);

        if (checkParam != null) {
            //使用SPEL进行key的解析
            ExpressionParser parser = new SpelExpressionParser();
            //SPEL上下文
            StandardEvaluationContext context = new StandardEvaluationContext();
            //把方法参数放入SPEL上下文中

            String[] check = checkParam.check();
            List<String> ruleList = new ArrayList<>();
            String[] msg = checkParam.msg();

            HashMap<String, Object> hashMap = new HashMap<>();

            List<String> fieldNames = new ArrayList<>();

            for (Object arg : args) {
                Field[] fields = ReflectUtil.getFields(arg.getClass());
                for (Field field : fields) {

                    for (String s : check) {
                        if (s.contains(field.getName())) {

                            fieldNames.add(field.getName());
                            Class<?> type = field.getType();
                            Object fieldValue = ReflectUtil.getFieldValue(arg, field.getName());




                            if (fieldValue == null) {
                                hashMap.put(field.getName(), null);
                                if(type == String.class)
                                {
                                    /**
                                     * 字符串空格处理
                                     */
                                    String c = s.replaceAll(" ", "");

                                    if(c.contains("\""+field.getName()+"!=''\""))
                                    {
                                        throw new MyException(field.getName()+"不能为空（校验）");
                                    }
                                }
                            }else {
                                if (type == String.class) {

                                    String v = (String) fieldValue;
                                    hashMap.put(field.getName(), v.trim());
                                } else {
                                    hashMap.put(field.getName(), fieldValue);
                                }
                            }

                            break;
                        }
                    }

                }
            }
            for (String s : check) {
                  String newS = s;
                /**
                 * 适配#
                 */
                for (String fieldName : fieldNames) {
                    if(s.contains(fieldName))
                    {
                        newS = newS.replaceAll("#" + fieldName, fieldName);
                        newS = newS.replaceAll(fieldName, "#" + fieldName);
                        if (!newS.startsWith("{")) {
                            newS = "{" + newS + "}";
                        }
                    }
                }
                ruleList.add(newS);
            }
            context.setVariables(hashMap);
            for (int i = 0; i < ruleList.size(); i++) {
                String c = ruleList.get(i);
                Boolean value = parser.parseExpression(c).getValue(context, Boolean.class);
                if (value != null && !value) {
                    if (msg.length > i && !StrUtil.isBlankIfStr(msg[i])) {
                        throw new MyException(msg[i]);
                    } else {
                        throw new MyException(c + "参数校验未通过");
                    }
                }
            }
        }
        return proceedingJoinPoint.proceed();
    }




    //            if(implementation.contains("userExecutionTask"))
//            {
//                //使用SPEL进行key的解析
//                ExpressionParser parser = new SpelExpressionParser();
//                //SPEL上下文
//                StandardEvaluationContext context = new StandardEvaluationContext();
//                //把方法参数放入SPEL上下文中
//                SpringExecutionTask springExecutionTask = run.getBean("springExecutionTask", SpringExecutionTask.class);
//
//                variables.put("springExecutionTask",springExecutionTask);
//                variables.put("variables",variables);
//
//
//
//                implementation  =  implementation.replace("{","")
//                        .replace("}","")
//                        .replace("userExecutionTask","springExecutionTask")
//                .replace("execution","#variables");
//                log.info("执行{}",implementation);
//
//                context.setVariables(variables);
//
//                Object value = parser.parseExpression(implementation).getValue(context);
//
//                System.out.println("value = " + value);
//
//            }
}
